<template>
  <scroll class="suggest"
          :data="results"
          :pullup="pullup"
          @scrollToEnd="loadMore"
          :listenScrollStart="listenScrollStart"
          @scrollStart='scrollStart'
          ref="scroll">
    <ul class="suggest-list">
      <li class="suggest-item"
          v-for="(item,index) in results"
          :key="index+'suggest'"
          @click="selectItem(item)">
        <div class="icon"><i :class="getIconCls(item)"></i></div>
        <div class="name">
          <p class="text"
             v-html="getDisplayName(item)"></p>
        </div>
      </li>
      <li v-show="hasMore">
        <loading></loading>
      </li>
    </ul>
    <div class="no-result-wrapper"
         v-show="!hasMore && results.length===0">
      <no-result title="没有相应的搜索结果"></no-result>
    </div>
  </scroll>
</template>

<script>
import { search } from 'api/search'
import { ERR_OK } from 'api/config'
import { createSong } from 'common/js/song'
import Scroll from 'base/scroll/scroll'
import Loading from 'base/loading/loading'
import Singer from 'common/js/singer'
import { mapMutations, mapActions } from 'vuex'
import NoResult from 'base/no-result/no-result'

const TYPE_SINGER = 'singer'
const PER_PAGE = 20

export default {
  name: 'suggest',
  props: {
    query: {
      type: String,
      default: ''
    },
    showSinger: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      page: 1,
      results: [],
      pullup: true,
      hasMore: true,
      listenScrollStart: true
    }
  },
  methods: {
    refresh () {
      this.$refs.scroll.refresh()
    },
    search () {
      this.page = 1
      this.hasMore = true
      this.results = []
      search(this.query, this.page, this.showSinger, PER_PAGE).then(resp => {
        if (resp.code === ERR_OK) {
          this.results = this._genResult(resp.data)
          this._checkHasMore(resp.data)
        }
      }).catch(e => {
        console.log(e.message)
      })
    },
    loadMore () {
      if (!this.hasMore) {
        return null
      } else {
        this.page++
        search(this.query, this.page, !this.showSinger, PER_PAGE).then(resp => {
          if (resp.code === ERR_OK) {
            this.results = this.results.concat(this._genResult(resp.data))
            this._checkHasMore(resp.data)
          }
        })
      }
    },
    getIconCls (item) {
      if (TYPE_SINGER === item.type) {
        return 'icon-mine'
      }
      return 'icon-music'
    },
    getDisplayName (item) {
      if (item.type === TYPE_SINGER) {
        return item.singername
      }
      return `${item.name}-${item.singer}`
    },
    selectItem (item) {
      if (item.type === TYPE_SINGER) {
        let singer = new Singer({
          id: item.singermid,
          name: item.singername
        })
        this.$router.push(`/singer/${singer.id}`)
        this.setSinger(singer)
      } else {
        this.insertSong(item)
      }
      this.$emit('select')
    },
    scrollStart () {
      this.$emit('scrollStarted')
    },
    _checkHasMore (data) {
      this.hasMore = !(!data.song.list.length || ((data.song.curnum + this.page * PER_PAGE) >= data.song.totalnum))
    },
    _genResult (data) {
      let ret = []
      if (data.zhida && data.zhida.singerid) {
        ret.push({ ...data.zhida, ...{ type: TYPE_SINGER } })
      }
      if (data.song) {
        ret = ret.concat(this._normalizeList(data.song.list))
      }
      return ret
    },
    _normalizeList (list) {
      let ret = []
      list.forEach(musicData => {
        let song = createSong({
          id: musicData.songid,
          mid: musicData.songmid,
          name: musicData.songname,
          album: {
            name: musicData.albumname,
            mid: musicData.albummid
          },
          interval: musicData.interval,
          singer: musicData.singer
        })
        if (!musicData.albummid) {
          song.image = `https://y.gtimg.cn/music/photo_new/T001R300x300M000${musicData.singer[0].mid}.jpg`
        }
        ret.push(song)
      })
      return ret
    },
    ...mapMutations({
      setSinger: 'SET_SINGER'
    }),
    ...mapActions(['insertSong'])
  },
  watch: {
    query (newVal) {
      this.search()
    }
  },
  components: {
    Scroll,
    Loading,
    NoResult
  }
}
</script>

<style lang="less" scoped>
@import "~common/css/variable";
@import "~common/css/mixin";
.suggest {
  height: 100%;
  overflow: hidden;
  .suggest-list {
    padding: 0 30px;
    .suggest-item {
      display: flex;
      align-items: center;
      padding-bottom: 20px;
    }
    .icon {
      flex: 0 0 30px;
      width: 30px;
      [class^="icon-"] {
        font-size: 14px;
        color: @color-text-d;
      }
    }
    .name {
      flex: 1;
      font-size: @font-size-medium;
      color: @color-text-d;
      overflow: hidden;
      .text {
        .no-wrap;
      }
    }
  }
  .no-result-wrapper {
    position: absolute;
    width: 100%;
    top: 50%;
    transform: translateY(-50%);
  }
}
</style>
